#include <windows.h>

#include "lib.h"
#include "cassrvc.h"
#include "slotserv.h"
#include "slotsproto.h"
#include "fileversion.h"
#include "getrand.h"

//
// NOTE:  uint32 getrand() is defined in "cassrvc.cpp"
//

class SlotsCasinoService : public CasinoService
{
	public:
		SlotsCasinoService();

		ServerInterface* createServer();
};

SlotsCasinoService::SlotsCasinoService()
	: CasinoService("Australian Slots", "Australian Slots Service", 2063)
{
//	lstrcpy(m_VersionStr, CASINO_RELEASENUM);
	m_VersionStr = CASINO_RELEASENUM;

    m_iProtoMajor = PROTO_VERSION1;
    m_iProtoMinor = PROTO_VERSION2;
}

ServerInterface*
SlotsCasinoService::createServer()
{
	return new SlotServer(port);
}

int
main(int argc, char* argv[])
{
    SlotsCasinoService service;
    
    // Parse for standard arguments (install, uninstall, version etc.)
	//
    if (!service.ParseStandardArgs(argc, argv))
	{
        // Didn't find any standard args so start the service
		//
        // Uncomment the DebugBreak line below to enter the debugger
        // when the service is started.
		//

#ifdef DEBUG
#if 0
		DebugBreak();
#endif
#endif

        service.StartService();
    }

    // When we get here, the service has been stopped
	//
    return service.m_Status.dwWin32ExitCode;
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 getRandomLessThan( uint32 nUpperBound )
///
/// @param   nUpperBound	The upper bound that the random number should be
///                         lower than.
///
/// This function gets a random number from 0 to less than the upper bound
/// with each possible result having an equal chance of being returned.
////////////////////////////////////////////////////////////////////////////
uint32 getRandomLessThan( uint32 nUpperBound )
{
    // getrand returns a uint32, so the maximum possible value is 0xFFFFFFFF
    uint32 nMaxRand = 0xFFFFFFFF;

    // Now if the maximum random value is not evenly divisible by the upper bound
    // of the random number they want, then the possible random values are not
    // evenly distributed across each possible result.  For example, if the maximum
    // possible random number were 25, and the upper bound was 10, then the values
    // 20 through 25 would skew the odds and cause the possible results of 0 through
    // 5 to occur slightly more often than 6 throuh 9.  So we need to calculate the
    // maximum random number that would result in an even distribution.  Any random
    // number that is greater than or equal to that should be thrown out so that the 
    // results are not skewed.

    // Divide the total number range by the upper bound to see how many evenly
    // distributed possibilities there are for each result.
    uint32 nNumChancesForEachResult = nMaxRand / nUpperBound;

    // Now calculate the maximum random value that would give us an equal
    // distribution among the possible results.
    uint32 nMaxRandForEqualDistribution = nNumChancesForEachResult * nUpperBound;

    // Declare a local variable to store the random number.
    uint32 nRand;

    do
    {
        // Get a random number.
        nRand = getrand();
    }
    // If the random number is greater than or equal to the maximum value for an 
    // equal distribution then throw it out and get another random value.
    // Note:  If nRand == nMaxEvenlyDistributedRand then a result of 0 would have
    // one extra chance to hit compared to the other possible results, so we have
    // to use >= for the loop condition to throw that value out as well.
    while ( nRand >= nMaxRandForEqualDistribution );

    // Now we know that the random number we have will not favor any result over the
    // others, so just divide it by the upper bound and return the remainder.
    // This will give you a random number within the range of 0 to less than
    // nUpperBound, with each possible result having an equal chance of hitting.
    return ( nRand % nUpperBound );
}

